import { Component, Input, ChangeDetectionStrategy, ViewChild } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { TabsModule } from './tabs.module';
import { TabsComponent } from './tabs.component';

@Component({
  template: `
    <lv-tabs 
      #tabsComponent
      [lvType]="lvType" 
      [lvTabBarExtraContent]="extraTpl"
      [(lvActiveIndex)]="index"
      [lvClosable]="lvClosable"
      (lvTabRemove)="removeTab($event)"
      (lvActiveIndexChange)="change($event)">
      <lv-tab *ngFor="let tab of tabs" [lvId]="tab.id" [lvTitle]="tab.name">
        This is content {{tab.name}}
      </lv-tab>

      <ng-template #extraTpl>
        <span style="display: inline-block; cursor: pointer;" (click)="addTab()"><i lv-icon='lv-icon-create'></i> 添加标签</span>
      </ng-template>
    </lv-tabs>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
class TestTabComponent {
  @Input() lvType: 'default' | 'card' = 'card';
  @Input() lvClosable = true;
  @Input() lvDisabled = true
  @Input() index:number = 0;

  @ViewChild('tabsComponent', { static: true }) tabsComponent: TabsComponent;

  tabs = Array.from({ length: 3 }).map((_, index) => ({ name: `Tab ${index}`, id: index }));

  removeTab(tab): void {
    const removeIndex = this.tabs.findIndex(item => tab.lvId === item.id);
    if (this.index === tab.lvId) {
      const currentIndex = this.tabs.findIndex(item => tab.lvId === item.id);
      const nextIndex = currentIndex === this.tabs.length - 1 ? currentIndex - 1 : currentIndex + 1;
      this.index = this.tabs[nextIndex]?.id;
    }
    this.tabs.splice(removeIndex, 1);
  }
  addTab(): void {
    const id = Number((Math.random() * 1000).toFixed(0));
    this.tabs.push({
      name: `Tab ${this.tabs.length + 1}`,
      id,
    });
    this.index = id;
  }

  change() {}
}
 
describe('TabsComponent', () => {
  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        declarations: [TestTabComponent],
        imports: [TabsModule, NoopAnimationsModule],
        teardown: { destroyAfterEach: true },
      }).compileComponents();
    })
  );

  describe('work', () => {
    let component: TestTabComponent;
    let fixture: ComponentFixture<TestTabComponent>;
    beforeEach(() => {
      fixture = TestBed.createComponent(TestTabComponent);
      component = fixture.componentInstance;
      fixture.autoDetectChanges();
    });

    it('work content remove', fakeAsync(() => {
      const tabContent = document.querySelector('.lv-tab-content');
      const tabItem = document.querySelector('.lv-tab-item');
      tabItem.dispatchEvent(new Event('click'));
      tick(500);
      fixture.detectChanges();
      expect(tabContent.textContent).toContain('This is content Tab 0');
      const closeButton = document.querySelector('.lv-tab-close');
      closeButton.dispatchEvent(new Event('click'));
      tick(500);
      fixture.detectChanges();
      const removeTab = document.querySelector('.lv-tab-content');
      expect(removeTab.textContent).toContain('This is content Tab 1');
    }));

    it('work content add', fakeAsync(() => {
      const tabContent = document.querySelector('.lv-tab-content');
      const tabItem = document.querySelector('.lv-tab-item');
      tabItem.dispatchEvent(new Event('click'));
      tick(500);
      fixture.detectChanges();
      expect(tabContent.textContent).toContain('This is content Tab 0');
      const addButton = document.querySelector('.lv-tabs-extra');
      const addIcon = addButton.querySelector('span');
      addIcon.dispatchEvent(new Event('click'));
      tick(2000);
      fixture.detectChanges();
      const addTab = document.querySelector('.lv-tab-content');
      expect(addTab.textContent).toContain('This is content Tab 4');
    }));

    it('work index', fakeAsync(() => {
      jest.spyOn(component, 'change');
      tick(2000);
      fixture.detectChanges();
      component.tabsComponent.tabChange(1, true);
      tick(2000);
      fixture.detectChanges();
      expect(component.change).toBeCalled();
    }));

  });
});
